<?php

namespace App\Http\Services;

use App\Http\Model\Ad;
use App\Http\Model\ColorGiftRateConfig;
use App\Http\Model\FinanceCharm;
use App\Http\Model\FinanceDiamond;
use App\Http\Model\FinanceKk;
use App\Http\Model\FinanceRoomWealth;
use App\Http\Model\Gift;
use App\Http\Model\GiftBag;
use App\Http\Model\FinanceRoomWallet;
use App\Http\Model\GiftClassificationConfig;
use App\Http\Model\GiftLibrary;
use App\Http\Model\Hint;
use App\Http\Model\Room;
use App\Http\Model\System;
use App\Http\Model\SystemConfig;
use App\Http\Model\User;
use App\Http\Model\FinanceUserWallet;
use App\Http\Model\FinanceWealth;
use App\Http\Model\UserVerify;
use App\Http\Model\Union;
use App\Lib\Publisher;
use Illuminate\Support\Facades\DB;
use App\Http\Model\Friends;
use App\Http\Model\UnionUser;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use Throwable;
use App\Http\Services\GameServices;
use App\Http\Services\ThinkingdataServices;
use App\Http\Model\Counter;
use Carbon\Carbon;

/*礼物service层*/

class GiftServices extends CommonServices
{
    protected $user;
    protected $diamond;//钻石
    protected $charm;//魅力
    protected $wealth;//财富
    protected $room_wealth;//财富
    protected $gift; //礼物库
    protected $giftBagModel; //礼物背包
    protected $kk; //金币
    protected $userWallet;
    protected $roomWallet;
    protected $ratioConf;
    protected $descConf;
    private $model_finance_user_wallet;
    protected $model_room;
    protected $redis_cache_time_gift = "CACHE:GIFT:RECKON:TIME:"; //计时礼物缓存
    protected $friendsModel;
    protected $modelUserVerify;
    protected $systemModel;
    protected $services_room_msg;
    protected $service_roomhostmicro;
    protected $service_roommicro;
    protected $service_finance;
    protected $service_msg;
    protected $groupChatMsgServices;
    protected $giftClassificationConfig;
    protected $union_model;
    protected $model_user_union;//公会成员model
    protected $gameService;
    protected $crossRoomPkService;//跨房PK
    protected $tdService;
    protected $colorGiftRateModel;//彩蛋礼物
    protected $colorGiftServices;//新版彩蛋逻辑
    protected $counterModel;
    protected $systemConfigModel;
    protected $roomProtectServices;

    protected $colorGiftRateRedis = 'COLOR:GIFT:RATE:LIST:'; //string 彩蛋奖池列表 COLOR:GIFT:RATE:LIST:{giftID}=>{json}
    protected $userSendColorGiftList = 'COLOR:GIFT:SEND:LIST:';//zset 用户获得礼物列表 COLOR:GIFT:SEND:LIST:{userId} => {int} {giftname}
    protected $userSendColorGiftInfo = 'COLOR:GIFT:SEND:CHARMINFO:';//zset 用户送礼主播魅力值列表 COLOR:GIFT:SEND:CHARMINFO:{userId} => {int} {userid}
    protected $userAwadColorGiftInfo = 'COLOR:GIFT:AWAD:LIST:';//zset 用户送礼主播收礼列表 COLOR:GIFT:AWAD:LIST:{userId} => {int} {giftNmae - userid}

    //主播收礼实时榜单
    protected $anchorAcceptGiftTimeRankKey = 'ANCHORACCEPTGIFT:TIMERANK:';//zset ANCHORACCEPTGIFT:TIMERANK:{user_id} => {积分}=>{user_id}
    //主播收礼每日榜单
    protected $anchorAcceptGiftDayRankKey = 'ANCHORACCEPTGIFT:DAYRANK:';//zset ANCHORACCEPTGIFT:DAYRANK:{user_id}:{day} => {积分}=>{user_id}

    public function __construct()
    {
        parent::__construct();

        $this->user = new User();
        $this->diamond = new FinanceDiamond();
        $this->charm = new FinanceCharm();
        $this->wealth = new FinanceWealth();
        $this->gift = new Gift();
        $this->giftBagModel = new GiftBag();
        $this->userWallet = new FinanceUserWallet();
        $this->roomWallet = new FinanceRoomWallet();
        $this->ratioConf = config('pay.wallet_change_ratio');
        $this->descConf = config('pay.wallet_change_desc');
        $this->model_finance_user_wallet = new FinanceUserWallet();
        $this->kk = new FinanceKk();
        $this->room_wealth = new FinanceRoomWealth();
        $this->model_room = new Room();
        $this->friendsModel = new Friends();
        $this->modelUserVerify = new UserVerify();
        $this->systemModel = new System();
        $this->services_room_msg = new RoomMsgServices();
        $this->service_roomhostmicro = RoomServicesInit::createHostMicro();
        $this->service_roommicro = RoomServicesInit::createMicro();
        $this->service_finance = new FinanceServices();
        $this->service_msg = new MsgServices();
        $this->groupChatMsgServices = new GroupChatMsgServices();
        $this->giftClassificationConfig = new GiftClassificationConfig();
        $this->union_model = new Union();
        $this->gameService = new GameServices();
        $this->model_user_union = new UnionUser();//公会成员服务
        $this->crossRoomPkService = new CrossRoomPkService();//跨房PK
        $this->tdService = new ThinkingdataServices();
        $this->colorGiftRateModel = new ColorGiftRateConfig();//彩蛋礼物配置奖池
        $this->colorGiftServices = new ColorGiftServices();
        $this->counterModel = new Counter();
        $this->roomProtectServices = new RoomProtectServices();
        $this->systemConfigModel = new SystemConfig();

    }

    //礼物商品列表 + 购买个数
    public function getGiftList($isShow, $page, $page_size, $room_id)
    {
        $user = $this->user->get_current_user();

        $typeWhere = [1,2, 3, 4, 5];
        $giftList = $this->gift->getGiftListData($isShow, $page, $page_size, $typeWhere);
        $total = $this->gift->getGiftTotal();
        $spec = $this->gift->getGiftSpec();
        $spec_list = [];
        if (!empty($spec)) {
            $spec_list = array_column($spec, 'spec_num');
        }

        $userId = $user['user_id'] ?? 0;

        foreach ($giftList as &$v) {
            $v['reckon_time'] = time();
        }
        unset($v);

        return ['list' => $giftList, 'spec_list' => $spec_list, 'page_index' => $page, 'page_count' => count($giftList), 'total' => $total, 'page_size' => $page_size];
    }


    //收到的礼物列表
    public function getObtainGiftList($userId, $page, $page_size)
    {
        //$userInfo = $this->user->get_current_user();
        //$userId = 0;
        //if(!empty($userInfo)){
        //  $userId = $userInfo['user_id'];
        //}
        $topEggId = ['98'];
        $giftList = $this->gift->getObtainGiftList($userId, $page, $page_size);
        $top = [];
        foreach($giftList as $k => $v){
            if(in_array($v['gift_id'],$topEggId)){
                $top[$k] = $v;
                unset($giftList[$k]);
            }
        }
        if(!empty($top)){
            $giftList = array_merge($top,$giftList);
        }
        $giftTotal = $this->gift->getObtainGiftTotal($userId);
        return ['list' => $giftList, 'page_index' => $page, 'page_count' => count($giftList), 'gift_total' => $giftTotal, 'page_size' => $page_size];
    }

    /**
     * 用户收到的礼物列表
     */
    public function userReceiveGiftList($userId, $showType, $limit, $page=0){
        $data = [
            'list' => []
        ];
        do {
            if(empty($userId)) {
                break;
            }
            $list = $this->gift->userReceiveGiftList($userId);
            //直播间
            if($showType == 1) {
                $list = array_column($list, null, 'gift_id');
                $counterGiftList = $this->counterModel->getCounterAll();
                $list2 = [];
                foreach($counterGiftList as $val) {
                    if($val['counter_cate_id'] == 52) {
                        continue;
                    }
                    if($val['is_show'] != 1) {
                        continue;
                    }
                    if(isset($list[$val['gift_id']])) {
                        $list2[] = $list[$val['gift_id']];
                    }else{
                        $val['user_id'] = $userId;
                        $val['gift_num'] = 0;
                        $list2[] = $val;
                    }
                }
                array_multisort(array_column($list2, 'price'), SORT_DESC, $list2);

                $list = $list2;
            }

            if(!empty($list)) {
                //分页
                $list = array_slice($list, $page*$limit, $limit);
            }
            foreach($list as $key=>$val) {
                $list[$key]['image'] = build_image($val['image']);
            }

            $data['list'] = $list;

        } while (false);

        return $data;
    }

    //检测账户
    public function checkWalletAndGift($to_user_num, $gift_id, $gift_num, &$giftInfo)
    {
        $now = time();
        $userInfo = $this->user->get_current_user();
        $userId = $userInfo['user_id'];

        $walletInfo = $this->model_finance_user_wallet->get_wallet($userId);
        $diamond_balance = $walletInfo['diamond_balance'];

        $giftInfo = $this->gift->getGift(['gift_id' => $gift_id], ['price', 'name']);
        $price = $giftInfo['price'];

        if ($diamond_balance < $price * $gift_num * $to_user_num) {
            return false;
        } else {
            return true;
        }

    }

    /**
     * 零钱凑整预备数组
     *
     * @param [int] $diamondTotal 总钻石数
     * @param [int] $rate 费率
     * @param [int] $kkTotal 金币
     * @param [int] $userid 用户id
     * @return array
     */
    public function kkUserCacheIncr($diamondTotal,$rate,$kkTotal,$userid){
        $kkUserCacheIncrList = []; //userid=>num;
        //如果发的金币单位是角 分的部分记录进缓存
        $kkUserCacheIncr = round( (($diamondTotal * $rate) - $kkTotal) * 100 );
        if($kkUserCacheIncr > 0) {
            $kkUserCacheIncrList[$userid] = $kkUserCacheIncr + (empty($kkUserCacheIncrList[$userid])?0:$kkUserCacheIncrList[$userid]);
        }
        return $kkUserCacheIncrList;
    }

    /**
     * 金币零钱凑整到账
     */
    public function kkUserCacheHandle($kkUserCacheIncrList=[], $roomId){
        if(!empty($kkUserCacheIncrList)) {
            $kk_desc = $this->descConf['kk_gift_rig'];
            foreach($kkUserCacheIncrList as $k3=>$v3) {
                $userNowKkNum = $this->kk->incrUserGiftGetKkLess($k3, $v3);
                $kkDecrNum = 0;
                if($userNowKkNum > 100) {
                    $kkDecrNum = intval($userNowKkNum/100)*100;
                }
                if($kkDecrNum > 0) {
                    try {
                        $userNowKkNum = $this->kk->decrUserGiftGetKkLess($k3, $kkDecrNum);
                        //处理
                        $kkDecrNum = round($kkDecrNum/100);//进制是100
                        $this->kk->inc($k3, 0, $roomId, 14, $kkDecrNum, $kk_desc);
                    } catch (\Exception $e) {
                        write_log('error_finance', '金币零钱凑整到账 记录失败', $k3.'-'.$kkDecrNum);
                    }
                }
            }
        }
    }


    /**
     * 礼品金额对私分成处理 收礼用户部分
     *
     * @param [int] $userid 用户id
     * @param [int] $diamondTotal 钻石礼物总数
     */
    public function privateUnionUserReward($userid,$diamondTotal,$room_id)
    {
        //默认取配置中的分成费率
//        $rate = $this->ratioConf['charm_to_kk'];
        $config=$this->systemConfigModel->getDefaultSystemConfig();
        //用户分成比例
        $rate = $config['charm_to_kk']['value'];
        //收礼用户是否是公会成员
        $unionId = $this->union_model->getUnionIdByUserId($userid);
        if(!empty($unionId)) {
            //当前房间所属公会信息
            $unionRoomInfo = $this->union_model->getUnionByRoomId($room_id);
            //主播和房间不是同一个公会不生效
            if($unionId == $unionRoomInfo['id']) {
                //获取公会信息
                $unionInfo =$this->union_model->getUnionInfo($unionId);
                //对私公会
                if($unionInfo['settle_type'] == 1) {
                    //对私查看是否公会长设置了对私分成比例
                    $rateInfo = $this->model_user_union->getUnionUserRate($unionInfo['id'],$userid,true);
                    //用户分成比例
                    $rate = empty($rateInfo) ? $rate : round($rateInfo['rate']/100,2);
                    if($rate < 0) {
                        $rate = 0;
                    }
                }
            }
        }
        //用户分得金币数
        $kkTotal = intval($diamondTotal * $rate);

        return ['kktotal'=>$kkTotal,'rate'=>$rate];  
    }
    /**
     * 对私公会结算处理
     *
     * @param [int] $userid 公会成员id
     * @param [int] $diamondTotal 价值总额
     * @param [int] $unionId 公会id
     * @return void
     */
    public function privateUnionReward($userid,$diamondTotal,$unionId, $userUnionId)
    {
        //获取公会信息
        $unionInfo =$this->union_model->getUnionInfo($unionId);
        $config=$this->systemConfigModel->getDefaultSystemConfig();
        //用户分成比例
//        $userRateBase = $this->ratioConf['charm_to_kk'];
        $userRateBase = $config['charm_to_kk']['value'];
        //会长分成比例
//        $rate = $this->ratioConf['union_gift_reward'];
        $rate = $config['union_gift_reward']['value'];
        //公会奖励类型 1=实时奖励

        if($unionInfo['reward_type'] == 1) {
//            $rate = $this->ratioConf['union_gift_reward_2'];
            $rate = $config['union_gift_reward_2']['value'];
        }
        //对私公会
        if($unionInfo['settle_type'] == 1) {
            //主播和房间不是同一个公会不生效
            if($unionId == $userUnionId) {
                //对私查看是否公会长设置了对私分成比例
                $rateInfo = $this->model_user_union->getUnionUserRate($unionId,$userid,true);
                //用户分成比例
                $userRate = empty($rateInfo['rate']) ? $userRateBase : round($rateInfo['rate']/100,2);
                //会长分成比例
                $rate = round(($rate + $userRateBase - $userRate), 2);
                if($rate < 0) {
                    $rate = 0;
                }
            }
        }
        //公会长分得金币数
        $kk_value = intval($diamondTotal*$rate);

        return ['kkvalue'=>$kk_value,'rate'=>$rate];
    }

    /**
     * 公会奖励 实时结算
     */
    public function sendGiftUnionReward($roomId, $dataValue, $fromUserId, $toUserId, $dataType, $dataId, $dataNum, $inPaipai)
    {
        do {
            if(empty($roomId)) {
                break;//不在房间
            }
            if(empty($dataValue)) {
                break;
            }
            //必须是CBD房间
            $roomInfo = $this->model_room->getRoomTypeByRoomId($roomId);
            if($roomInfo['business_type'] != 1) {
                break;//非BCD房间
            }
            //公会房间信息
            $unionInfo = $this->union_model->getUnionByRoomId($roomId);
            if(empty($unionInfo)) {
                break;//不是公会房间
            }
            $unionId = $unionInfo['id'];
            //收礼用户是否是公会成员
            $userUnionId = $this->union_model->getUnionIdByUserId($toUserId);
            $config=$this->systemConfigModel->getDefaultSystemConfig();
            //分成开关
            $union_gift_reward_3=$config['union_gift_reward_3']['value'];
            if($union_gift_reward_3==1){
                if(empty($userUnionId)) {
                    if($inPaipai == 1) {
                        $userUnionId = $unionId;
                    }
//                    else{
//                        break;
//                    }
                }
            }else{
                break;
            }


            //房间绑定实时结算用户
            $financeUserId = $this->model_room->getRoomFinanceUserTable($roomId);
            $financeUserId = empty($financeUserId) ? $unionInfo['un_user_id'] : $financeUserId;

            //记录公会房间流水
            $log = [
                'union_id' => $unionId,
                'room_id' => $roomId,
                'user_id' => $toUserId,
                'from_user_id' => $fromUserId,
                'data_type' => $dataType,//类型 1=购买礼物 2=背包礼物 3=宝箱
                'data_value' => $dataValue,
                'data_id' => $dataId,
                'data_num' => $dataNum,
                'user_union_id' => $userUnionId,
                'finance_user_id' => $financeUserId,
            ];
            $this->union_model->adduUnionRoomStream($log);

            //公会奖励 实时结算 发放
            $ratioConf = config('pay');
            //对私公会或者非对私公会处理
            $diamondTotal = $dataValue * $dataNum;
            $res = $this->privateUnionReward($toUserId,$diamondTotal,$unionId, $userUnionId);
            $kk_value = $res['kkvalue'];
            $kk_desc = $ratioConf['wallet_change_desc']['room_gift_union_kk_5'];
            if($unionId == $userUnionId) {
                $kk_desc = $ratioConf['wallet_change_desc']['room_gift_union_kk_0'];
            }

            //会长
            $this->kk->inc($financeUserId, $toUserId, $roomId, 41, $kk_value, $kk_desc);
            //零钱凑整
            $kkUserCacheIncrList = $this->kkUserCacheIncr($diamondTotal,$res['rate'],$kk_value,$financeUserId);
            $this->kkUserCacheHandle($kkUserCacheIncrList, $roomId);

        } while (false);
    }

    
    /**
     * 获取预加载资源
     * @return array
     */
    public function get_animate_resources()
    {
        return $this->gift->get_animate_resources();
    }

    /**
     * 获取今天房间礼物流水
     * @param $room_id
     * @return mixed
     */
    public function get_day_room_log($room_id, $page_index, $page_size)
    {
        $lasteWeekStart = Carbon::now()->subWeek()->startOfWeek()->timestamp;
        $thisWeekEnd = Carbon::now()->endOfWeek()->timestamp;

        $data = $this->gift->room_stream($room_id, $lasteWeekStart, $thisWeekEnd, $page_index, $page_size);
        foreach ($data as $k => $v) {
            $user = $this->user->get_user($v['user_id']);
            $from_user = $this->user->get_user($v['from_user_id']);
            $data[$k]['user_nickname'] = $user['nickname'];
            $data[$k]['from_user_nickname'] = $from_user['nickname'];
            $data[$k]['from_user_images'] = $from_user['images'];
            $data[$k]['user_images'] = $user['images'];
            if (isset($from_user['thumbnails'])) {
                $data[$k]['from_user_images'] = $from_user['thumbnails'];
            }
            if (isset($user['thumbnails'])) {
                $data[$k]['user_images'] = $user['thumbnails'];
            }
        }
        return ['list' => $data, 'page_index' => intval($page_index), 'page_count' => count($data), 'page_size' => intval($page_size)];
    }


    //验证礼物信息
    public function checkGiftTypeByGiftId($gift_id)
    {
        $gift_info = $this->gift->getGift(['gift_id'=>$gift_id],['gift_id','gift_type']);
        //礼物类型
        return $gift_info['gift_type'];
    }



    ################# 后台调用 ##########################################


    /**
     * 礼物更新
     * */
    public function giftUpdate()
    {
        $code = Hint::SUCCESS;
        $msg = Hint::getErrCodeMsg($code);
        $data = [];

        do {
            try {
                $this->I('gift_id', '礼物ID', 'int', true, '礼物ID不能为空');
                $this->I('name', '礼物名称', 'string', false, '礼物名称不能为空');
                $this->I('price', '价格', 'int', false, '价格不能为空');// 单位：钻石
                $this->I('image', '礼物图片', 'string', false, '礼物图片不能为空');
                $this->I('animate_resource', '动画资源包链接', 'string', false);
                $this->I('animate_resource_md5', '动画资源md5值', 'string', false);
                $this->I('is_show', '是否显示商品', 'int', false);// 1:是 0:否
                $this->I('gift_sort', '礼物商品显示排序', 'int', false);// 值越小排序越靠前
                $this->I('gift_type', '类型', 'int', true);//类型 1=普通礼物 2=幸运礼物 3=盲盒礼物 4=富豪值礼物 5=彩蛋礼物 6=套盒礼物 7=新幸运礼物 8=增值服务 9=礼物抵扣券 10=热度值礼物
                $this->I('wealth_num', '自定义富豪值', 'int', false);// 自定义富豪值
                $this->I('hot_num', '自定义热度值', 'int', false);// 自定义热度值
                $this->I('ext_data', '扩展字段', 'string', false);

                $variables = [];
                $checkParams = $this->check($this->requestData, $variables); //校验数据
                extract($checkParams);
                if ($code !== Hint::SUCCESS) {
                    break;
                }
                extract($variables); //数组参数化

                $giftId = $this->requestData['gift_id'];
                // 移除请求数据中的ID
                unset($this->requestData['gift_id']);

                if (empty($this->requestData)) {
                    $code = Hint::ERR_PARAMS_CHECK_FAIL;
                    $msg = Hint::getErrCodeMsg($code) . ':至少包含任意一个业务参数';
                    break;
                }

                //如果是幸运礼物 检查概率
                if($this->requestData['gift_type']==2 && $this->requestData['is_show']==1) {
                    //todo
                    $giftLuckPool = $this->gift->getGiftLuckPoolByGiftId($giftId);
                    if(empty($giftLuckPool)) {
                        $code = Hint::ERR_PARAMS_CHECK_FAIL;
                        $msg = '幸运礼物奖池未配置';
                        break;
                    }
                    $giftLuckPoolMap = array_column($giftLuckPool, 'multiple_num');
                    if(count($giftLuckPool) != count($giftLuckPoolMap)) {
                        $code = Hint::ERR_PARAMS_CHECK_FAIL;
                        $msg = '幸运礼物奖池倍数存在重复';
                        break;
                    }
                    $rateSum = array_sum(array_column($giftLuckPool, 'base_rate'));
                    if($rateSum != 10000) {
                        $code = Hint::ERR_PARAMS_CHECK_FAIL;
                        $msg = '幸运礼物奖池总概率不是100%';
                        break;
                    }
                }
                //富豪值礼物
                if($this->requestData['gift_type'] == 4) {
                    $this->requestData['price'] = 0;
                }

                $upData = $this->requestData;
                //礼物抵扣券
                if(in_array($upData['gift_type'], [9])) {
                    $upData['is_show'] = 0;

                    if(empty($upData['ext_data'])) {
                        $ext_data = json_decode($upData['ext_data'], true);
                        if(empty($ext_data) || empty($ext_data['to_gift_id'])) {
                            $code = Hint::PARAM_ERROR;
                            $msg = '礼物抵扣券 抵扣礼物ID 必须配置 ';
                            break;
                        }
                        //判断是否存在
                        $check = $this->gift->checkGiftDeduct($giftId, $ext_data['to_gift_id']);
                        if($check) {
                            $code = Hint::PARAM_ERROR;
                            $msg = '礼物抵扣券 配置的 抵扣礼物ID 已被配置, 不可重复配置 ';
                            break;
                        }

                    }
                }else{
                    unset($upData['ext_data']);
                }

                $this->gift->singleUpdate(['gift_id' => $giftId], $upData);

                $this->gift->clearGiftCache(intval($giftId));
                $data['gift_id'] = intval($giftId);

            } catch (\Exception $e) {
                $code = Hint::ERR_SYS_FAIL;
                $msg = 'message：' . $e->getMessage() . '，line：' . $e->getLine();
                break;
            }
        } while (false);

        return compact('code', 'msg', 'data');
    }

    //检测用户是否为账号异常
    public function checkAbnormalUser($to_user_ids)
    {
        $code = Hint::SUCCESS;
        $msg = Hint::getErrCodeMsg($code);
        $data = [];

        $users = $this->user->get_users_by_ids($to_user_ids);

        if ($users) {
            $is_abnormal = 1;

            $res = array_values(array_filter($users, function($param) use ($is_abnormal) {
                return $param['is_abnormal'] == $is_abnormal;
            }));

            if ($res) {
                $code = Hint::USER_ACCOUNT_IS_ABNORMAL;
                $msg = Hint::getErrCodeMsg($code);
                $data['user_ids'] = array_column($res, 'user_id');
                $data['user_nicknames'] = array_column($res, 'nickname');
            }
        }
        return compact('code', 'msg', 'data');
    }

    public function getInteractRule(){
        $code = Hint::SUCCESS;
        $msg = Hint::getErrCodeMsg($code);
        $res = $this->gift->getInteractRule();
        foreach ($res as $k=>$v){
            $data[] = json_decode($v);
        }
        return compact('code', 'msg', 'data');
    }

    public function adOfCanSend($userId) {
        $ad = (new Ad())->get_banner(3);
        $userWalletData = $this->model_finance_user_wallet->get_wallet($userId);
        $is = false;
        foreach($ad as $item) {
            $redisKey = sprintf('AD:WEALTH_MSG:%s:%s', $item['id'], $userId);
            if($userWalletData['wealth_balance'] >= $item['wealth_value'] && !Redis::GET($redisKey)) {
                Redis::SET($redisKey, 1);
                $is = true;
                break;
            }
        }
        return true === $is ? $ad : [];
    }

    /**
     * 根据本次送出礼物价值，获得价值级别，客户端有不同处理
     *
     * @param int $totalPrice
     * @return int
     */
    public function getGiftValueLevel($totalPrice) 
    {
        $position = config('animation.position');

        $type = 0;
        if ($totalPrice >= $position['a'] && $totalPrice < $position['b']) {
            $type = 1;  // a
        }
        if ($totalPrice >= $position['b'] && $totalPrice < $position['c']) {
            $type = 2;  // a,b
        }
        if ($totalPrice >= $position['c'] && $totalPrice < $position['d']) {
            $type = 3;  // a,b,c
        }
        if ($totalPrice >= $position['d']) {
            $type = 4;  // a,b,c,d
        }
        return $type;
    }

    /**
     * 根据礼物ID获取礼物信息
     *
     * @param array $giftIds
     * @return void
     */
    public function getGiftListByIds($giftIds)
    {
        $giftCond[] = [
            function ($query) use ($giftIds) {
                $query->whereIn('gift_id', $giftIds);
            },
        ];
        return $this->gift->getListByCondition($giftCond, ['gift_id', 'price', 'name']);
    }

    /**
     * 设置幸运礼物奖池
     */
    public function setLuckGiftPoll($giftId, $poolList){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        do {
            if (empty($poolList)) {
                $code = Hint::PARAM_ERROR;
                $msg = '奖池参数错误';
                break;
            }
            //礼物信息获取
            $giftInfo = $this->gift->getGift(['gift_id' => $giftId], ['price', 'gift_type', 'is_show']);
            if(empty($giftInfo)) {
                $code = Hint::PARAM_ERROR;
                $msg = '礼物数据获取失败';
                break;
            }
            if($giftInfo['gift_type'] != 2) {
                $code = Hint::PARAM_ERROR;
                $msg = '礼物不是幸运礼物';
                break;
            }

            //上锁
            $lockKey = 'LOCK:SETLUCKGIFTPOOL:'.$giftId;
            if (!redis_lock($lockKey, 60)) {
                $code = Hint::PARAM_ERROR;
                $msg = '当前已经在处理中,不可重复请求';
                break;
            }

            //修改礼物显示
            $this->gift->singleUpdate(['gift_id' => $giftId], ['is_show'=>0]);
            $this->gift->clearGiftCache(intval($giftId));

            $poolMap = $this->gift->getGiftLuckPoolByGiftId($giftId);
            $poolMap = array_column($poolMap, null, 'multiple_num');

            //处理
            $poolIds = [];
            foreach($poolList as $val) {
                if(empty($poolMap[$val['multiple_num']])) {
                    //新增奖池
                    $log = [
                        'gift_id' => $giftId,
                        'multiple_num' => (int) $val['multiple_num'],
                        'diamond_num' => (int) $val['diamond_num'],
                        'base_rate' => (int) $val['base_rate'],
                    ];
                    $id = $this->gift->insertGiftLuckPool($log);
                }else{
                    $id = $poolMap[$val['multiple_num']]['id'];
                    $log = [
                        'gift_id' => $giftId,
                        'multiple_num' => (int) $val['multiple_num'],
                        'diamond_num' => (int) $val['diamond_num'],
                        'base_rate' => (int) $val['base_rate'],
                    ];
                    $this->gift->updateGiftLuckPool($id, $log);
                }
                $poolIds[] = $id;
            }
            //删除旧的
            $this->gift->deleteGiftLuckPool($giftId, $poolIds);

            //解锁
            redis_unlock($lockKey, 60);

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 新增礼物
     */
    public function addGift($params=[]){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        do {
            //默认不显示
            if(in_array($params['gift_type'], [2,6,9])) {
                $params['is_show'] = 0;
            }
            //无价值
            if(in_array($params['gift_type'], [4])) {
                $params['price'] = 0;
            }

            //礼物抵扣券
            if(in_array($params['gift_type'], [9])) {
                $ext_data = json_decode($params['ext_data'], true);
                if(empty($ext_data) || empty($ext_data['to_gift_id'])) {
                    $code = Hint::PARAM_ERROR;
                    $msg = '礼物抵扣券 抵扣礼物ID 必须配置 ';
                    break;
                }
                //判断是否存在
                $check = $this->gift->checkGiftDeduct(0, $ext_data['to_gift_id']);
                if($check) {
                    $code = Hint::PARAM_ERROR;
                    $msg = '礼物抵扣券 配置的 抵扣礼物ID 已被配置, 不可重复配置 ';
                    break;
                }

            }else{
                unset($params['ext_data']);
            }

            $giftId = $this->gift->insertSingle($params);
            if($giftId <= 0) {
                $code = Hint::ERR_DATA_CREATE_FAIL;
                break;
            }
        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 设置套盒礼物奖池
     */
    public function setSetboxGiftPool($giftId, $extData){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        do {
            if(empty($giftId) || empty($extData)) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            //获取礼物信息
            $giftInfo = $this->gift->getSingle(['gift_id'=>$giftId], ['gift_id','gift_type'], true);
            if(empty($giftInfo) || $giftInfo['gift_type']!=6) {
                $code = Hint::PARAM_ERROR;
                $msg = '礼物不是套盒礼物';
                break;
            }
            //包含礼物
            foreach($extData as $val) {
                $giftInfoV2 = $this->gift->getSingle(['gift_id'=>$val], ['gift_id','gift_type'], true);
                if(empty($giftInfoV2) || $giftInfoV2['gift_type']!=1) {
                    $code = Hint::PARAM_ERROR;
                    $msg = '包含礼物不是钻石礼物:'.$val;
                    break;
                }
            }
            if($code != Hint::SUCCESS) {
                break;
            }
            $params['ext_data'] = json_encode($extData);

            $this->gift->singleUpdate(['gift_id' => $giftId], $params);
            $this->gift->clearGiftCache(intval($giftId));

        } while (false);

        return compact('code', 'msg', 'data');
    }

    //设置彩蛋礼物奖池
    public function setColorGiftPool($gift_id, $child_gift_id, $rate, $poolId){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        do {
            $data = $this->colorGiftRateModel->setColorGiftPool($gift_id, $child_gift_id, $rate, $poolId);
            if(!$data){
                break;
            }
        }while(false);
        return compact('code', 'msg', 'data');
    }
    
    //设置彩蛋礼物上线配置
    public function setColorGiftMax($maxOut,$maxIn){
        $res = $this->colorGiftRateModel->setColorGiftMax($maxOut,$maxIn);
        return $res;
    }

    /**
     * 新幸运礼物新增奖池
     */
    public function luckGiftAddPool($poolName, $minNum, $maxNum, $giftPrice){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        do {
            if(empty($poolName) || empty($minNum) || empty($maxNum) || empty($giftPrice)) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            //新增
            $poolId = $this->gift->luckGiftAddPool($poolName, $minNum, $maxNum, $giftPrice);

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 新幸运礼物编辑奖池
     */
    public function luckGiftEditPool($poolId, $poolName, $minNum, $maxNum, $giftPrice){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        do {
            if(empty($poolId)) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            $pool = $this->gift->getLuckGiftPool();
            if(empty($pool[$poolId])) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            //奖池需关闭才可改
            if($pool[$poolId]['status'] != 2) {
                $code = Hint::PARAM_ERROR;
                $msg = '奖池未关闭';
                break;
            }

            //更新
            $this->gift->editLuckGiftPool($poolId, ['pool_name'=>$poolName, 'min_num'=>$minNum, 'max_num'=>$maxNum, 'gift_price'=>$giftPrice]);

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 新幸运礼物新增奖池配置
     */
    public function luckGiftAddPoolConfig($poolId, $diamondNum, $dataNum){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        do {
            if(empty($poolId)) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            $pool = $this->gift->getLuckGiftPool();
            if(empty($pool[$poolId])) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            //奖池需关闭才可改
            if($pool[$poolId]['status'] != 2) {
                $code = Hint::PARAM_ERROR;
                $msg = '奖池未关闭';
                break;
            }

            //新增
            $this->gift->luckGiftAddPoolConfig($poolId, $diamondNum, $dataNum);

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 新幸运礼物编辑奖池配置
     */
    public function luckGiftEditPoolConfig($id, $diamondNum, $dataNum){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        do {
            if(empty($id)) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            $info = $this->gift->getLuckGiftAddPoolConfigById($id);
            if(empty($info)) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            $poolId = $info['pool_id'];
            $pool = $this->gift->getLuckGiftPool();
            if(empty($pool[$poolId])) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            //奖池需关闭才可改
            if($pool[$poolId]['status'] != 2) {
                $code = Hint::PARAM_ERROR;
                $msg = '奖池未关闭';
                break;
            }

            //更新
            $this->gift->editLuckGiftPoolConfig($poolId, $id, ['diamond_num'=>$diamondNum, 'data_num'=>$dataNum]);

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 新幸运礼物删除奖池配置
     */
    public function luckGiftDelPoolConfig($id){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        do {
            if(empty($id)) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            $info = $this->gift->getLuckGiftAddPoolConfigById($id);
            if(empty($info)) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            $poolId = $info['pool_id'];
            $pool = $this->gift->getLuckGiftPool();
            if(empty($pool[$poolId])) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            //奖池需关闭才可改
            if($pool[$poolId]['status'] != 2) {
                $code = Hint::PARAM_ERROR;
                $msg = '奖池未关闭';
                break;
            }

            //更新
            $this->gift->editLuckGiftPoolConfig($poolId, $id, ['is_delete'=>1]);

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 新幸运礼物更新奖池缓存
     */
    public function luckGiftPoolReset($poolId){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        do {
            try {
                if(empty($poolId)) {
                    $code = Hint::PARAM_ERROR;
                    $msg = '更新奖池缓存异常:参数错误';
                    break;
                }
                $poolList = $this->gift->getLuckGiftPoolConfig($poolId);
                if(empty($poolList)) {
                    $code = Hint::PARAM_ERROR;
                    $msg = '更新奖池缓存异常:数据获取失败';
                    break;
                }
                $poolList = array_column($poolList, 'data_num', 'diamond_num');

                $this->gift->makeLuckGiftPoolData($poolId, $poolList);

            } catch (\Exception $e) {
                $code = Hint::ERROR;
                $msg = '更新奖池缓存异常:'.$e->getMessage();
                break;
            }

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 新幸运礼物设置奖池开启/关闭
     */
    public function luckGiftSetPoolStatus($poolId, $poolStatus){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        do {
            if(empty($poolId) || empty($poolStatus)) {
                break;
            }
            $pool = $this->gift->getLuckGiftPool();
            if(empty($pool[$poolId])) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            $poolInfo = $pool[$poolId];
            $poolStatus = ($poolStatus==1) ? 1 : 2;
            //开启
            if($poolStatus == 1) {
                //区间内的奖池必须关闭
                $flag = 0;
                $openPool = [];//已开启的奖池
                foreach($pool as $val) {
                    if($val['status']==1 && $val['gift_price']==$poolInfo['gift_price']) {
                        $openPool = $val;
                        if($val['min_num']<=$poolInfo['min_num'] && $poolInfo['min_num']<=$val['max_num']) {
                            $code = Hint::PARAM_ERROR;
                            $msg = 'ERROR 1:与现有生效奖池'.$val['pool_name'].'（'.$val['id'].'）区间重合，请重新配置:';
                            $flag = 1;
                            break;
                        }
                        if($val['min_num']<=$poolInfo['max_num'] && $poolInfo['max_num']<=$val['max_num']) {
                            $code = Hint::PARAM_ERROR;
                            $msg = 'ERROR 2:与现有生效奖池'.$val['pool_name'].'（'.$val['id'].'）区间重合，请重新配置:';
                            $flag = 1;
                            break;
                        }
                        if($poolInfo['min_num']<=$val['min_num'] && $val['min_num']<=$poolInfo['max_num']) {
                            $code = Hint::PARAM_ERROR;
                            $msg = 'ERROR 3:与现有生效奖池'.$val['pool_name'].'（'.$val['id'].'）区间重合，请重新配置:';
                            $flag = 1;
                            break;
                        }
                        if($poolInfo['min_num']<=$val['max_num'] && $val['max_num']<=$poolInfo['max_num']) {
                            $code = Hint::PARAM_ERROR;
                            $msg = 'ERROR 4:与现有生效奖池'.$val['pool_name'].'（'.$val['id'].'）区间重合，请重新配置:';
                            $flag = 1;
                            break;
                        }
                    }
                }
                if($flag == 1) {
                    break;
                }

                //奖池配置数据是否有效
                $poolList = $this->gift->getLuckGiftPoolConfig($poolId);
                if(empty($poolList)) {
                    $code = Hint::PARAM_ERROR;
                    $msg = '获取奖池配置失败';
                    break;
                }
                $flag = 0;
                $numAll = 0;
                foreach($poolList as $val) {
//                    if(empty($val['diamond_num'])) {
//                        $code = Hint::PARAM_ERROR;
//                        $msg = '奖池配置 序号'.$val['item_no'].'返奖钻石数为0';
//                        $flag = 1;
//                        break;
//                    }
                    $numAll = $numAll + $val['data_num'];
                }
                if($numAll < 1) {
                    $code = Hint::PARAM_ERROR;
                    $msg = '奖池配置 数量总和不足1';
                    $flag = 1;
                }
                if($flag == 1) {
                    break;
                }

                //重制奖池
                $res = $this->luckGiftPoolReset($poolId);
                if($res['code'] != Hint::SUCCESS) {
                    return $res;
                }
            }

            $res = $this->gift->editLuckGiftPool($poolId, ['status'=>$poolStatus]);

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 新幸运礼物奖池配置剩余数量
     */
    public function luckGiftPoolConfigNum($poolId){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        do {
            try {
                if(empty($poolId)) {
                    $code = Hint::PARAM_ERROR;
                    break;
                }
                $poolList = $this->gift->getLuckGiftPoolConfig($poolId);
                if(empty($poolList)) {
                    $code = Hint::PARAM_ERROR;
                    break;
                }

                $hasList = $this->gift->getLuckGiftPoolData($poolId);
                $hasList = array_column($hasList, 'num', 'id');

                foreach($poolList as $key=>$val) {
                    $val['less_num'] = empty($hasList[$val['diamond_num']]) ? 0 : $hasList[$val['diamond_num']];
                    $val['draw_num'] = $val['data_num'] - $val['less_num'];

                    $poolList[$key] = $val;
                }
                $data = $poolList;

            } catch (\Exception $e) {
                $code = Hint::ERROR;
                $msg = '异常:'.$e->getMessage();
                break;
            }

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 新幸运礼物新增白名单
     */
    public function luckGiftAddWhite($userId, $diamondNum, $adminId){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        do {
            if(empty($userId) || empty($diamondNum)) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            //新增
            $whiteId = $this->gift->luckGiftAddWhite($userId, $diamondNum, $adminId);

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 新幸运礼物删除白名单
     */
    public function luckGiftDelWhite($whiteId){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        do {
            if(empty($whiteId)) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            $res = $this->gift->luckGiftDelWhite($whiteId);

        } while (false);

        return compact('code', 'msg', 'data');
    }
    //主播收礼排行榜
    protected function handleAnchorAcceptGiftRank($streamList) {
        try {
            $ymd = date('Ymd');
            foreach($streamList as $val) {
                $giftPrice = $val['base_gift_price']*$val['gift_num'];
                if($giftPrice <= 0) {
                    continue;
                }
                //收礼用户是否是主播
                $unionInfo = $this->union_model->getUserUnionInfo($val['user_id']);
                if(empty($unionInfo)) {
                    continue;
                }

                //主播收礼实时榜单
                $cacheKey = $this->anchorAcceptGiftTimeRankKey.$val['user_id'];
                Redis::zincrby($cacheKey, $giftPrice, $val['from_user_id']);
                Redis::expire($cacheKey, 86400*300);

                //主播收礼每日榜单
                $cacheKey = $this->anchorAcceptGiftDayRankKey.$val['user_id'].':'.$ymd;
                Redis::zincrby($cacheKey, $giftPrice, $val['from_user_id']);
                Redis::expire($cacheKey, 86400*7);
            }
        } catch (\Exception $e) {
            write_log('error_sendGift', 'handleAnchorAcceptGiftRank', ['streamList'=>$streamList, 'msg'=>$e->getMessage(), 'line'=>$e->getLine()]);
            return false;
        }
    }

    /**
     * 背包礼物来源类型
     */
    public function bagGiftPlatformType(){
        $data = $this->giftBagModel->bagGiftPlatformType();

        return $data;
    }







}
